package com.admin4j.server.system.service.impl;

import com.admin4j.common.util.UserContextUtil;
import com.admin4j.framework.security.authorization.HttpUrlPermission;
import com.admin4j.framework.security.authorization.IPermissionUrlService;
import com.admin4j.server.system.entity.SysPermission;
import com.admin4j.server.system.entity.dto.PermissionDTO;
import com.admin4j.server.system.mapper.SysPermissionMapper;
import com.admin4j.server.system.service.ISysPermissionService;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.CacheManager;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.template.QuickConfig;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 资源权限表 服务实现类
 * </p>
 *
 * @author andanyang
 * @since 2023-12-19
 */
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements ISysPermissionService, IPermissionUrlService {

    @Autowired
    CacheManager cacheManager;

    @Autowired
    SysPermissionMapper sysPermissionMapper;

    // 所有权限
    Cache<String, List<HttpUrlPermission>> allPermissionUrlCache;
    // 权限http url
    Cache<Long, PermissionDTO> myPermissionUrlCache;


    @PostConstruct
    public void init() {
        QuickConfig qc = QuickConfig.newBuilder("allPermissionUrl")
                .cacheType(CacheType.BOTH) // two level cache
                .localLimit(1)
                .syncLocal(true) // invalidate local cache in all jvm process after update
                .build();
        allPermissionUrlCache = cacheManager.getOrCreateCache(qc);

        qc = QuickConfig.newBuilder("myPermissions:")
                .expire(Duration.ofHours(2))
                .cacheType(CacheType.BOTH) // two level cache
                .localLimit(1000)
                .syncLocal(true) // invalidate local cache in all jvm process after update
                .build();

        myPermissionUrlCache = cacheManager.getOrCreateCache(qc);
    }

    // 用户的权限code 集合
    @Override
    public List<String> permissionCodes(Long userId) {
        PermissionDTO permission = getMyPermissionDTO(userId);

        return permission.getCodes();
    }

    @Override
    public boolean ignoreCheck() {
        // return UserContextUtil.isAdmin();
        return false;
    }

    /**
     * 获取 系统 所有的 PermissionUri
     *
     * @return
     */
    @Override
    public List<HttpUrlPermission> allPermissionUrl() {


        return allPermissionUrlCache.computeIfAbsent("", key -> {

                    List<SysPermission> sysPermissions = sysPermissionMapper.allPermissionUri();
                    List<HttpUrlPermission> httpUrlPermissions = new ArrayList<>();
                    for (SysPermission sysPermission : sysPermissions) {

                        httpUrlPermissions.add(new HttpUrlPermission(getHttpMethodByValue(sysPermission.getHttpMethod()), sysPermission.getUri()));
                    }
                    return httpUrlPermissions;
                }
        );
    }


    /**
     * 当前用户拥有的权限
     *
     * @return
     */
    @Override
    public List<HttpUrlPermission> getMyPermissionUrls() {

        PermissionDTO permission = getMyPermissionDTO(UserContextUtil.getUserId());

        return permission.getHttpUrls();
    }

    protected PermissionDTO getMyPermissionDTO(Long userId) {

        return myPermissionUrlCache.computeIfAbsent(userId, key -> {

                    PermissionDTO permissionDTO = new PermissionDTO();
                    List<SysPermission> sysPermissions = sysPermissionMapper.getPermissionsByUserId(key);
                    for (SysPermission sysPermission : sysPermissions) {
                        permissionDTO.getCodes().add(sysPermission.getPermissionCode());
                        permissionDTO.getHttpUrls().add(new HttpUrlPermission(getHttpMethodByValue(sysPermission.getHttpMethod()), sysPermission.getUri()));
                    }
                    return permissionDTO;
                }
        );
    }

    // int 转 HttpMethod
    // http 方法; 0 全部 1    GET,2    HEAD,3    POST,4    PUT,5    PATCH,6    DELETE,7    OPTIONS,8   TRACE;
    private HttpMethod getHttpMethodByValue(Integer value) {

        switch (value) {
            case 0:
                return null;
            case 1:
                return HttpMethod.GET;
            case 2:
                return HttpMethod.HEAD;
            case 3:
                return HttpMethod.POST;
            case 4:
                return HttpMethod.PUT;
            case 5:
                return HttpMethod.PATCH;
            case 6:
                return HttpMethod.DELETE;
            case 7:
                return HttpMethod.OPTIONS;
            case 8:
                return HttpMethod.TRACE;
            default:
                return null;
        }
    }


    /**
     * 清除个人缓存
     *
     * @param userId
     */
    @Override
    public void clearCache(Long userId) {

        myPermissionUrlCache.remove(userId);
    }
}
